/*-----------------------------------------------------------------------------
 * @file   bat_zhiann.h
 * @brief  Driver for a Zhiann Smart Battery by CAN BUS
 * Only support single battery for now
 * @author WLH<wanglehui8357@163.com> Copyright (C) 2021~2099.
-----------------------------------------------------------------------------*/
#ifndef BAT_ZHIANN_H
#define BAT_ZHIANN_H

#include "hal_can.h"

BEGIN_DECLS

/*-----------------------------------------------------------------------------
 * Macros define
-----------------------------------------------------------------------------*/
#define ZHIANN_BAT_MAX_CELL_CNT 18u

/*-----------------------------------------------------------------------------
 * DataType ID and Signature defines
-----------------------------------------------------------------------------*/
#define ZHIANN_NODE_STATUS_ID  341
#define ZHIANN_BAT_ID1_ID      20302
#define ZHIANN_BAT_ID2_ID      20303
#define ZHIANN_BAT_CMD_ID      245
#define ZHIANN_BAT_INFO_ID     1092
#define ZHIANN_BAT_AUX_INFO_ID 20004

#define IS_ZHIANN_BAT_MSG_ID(id)     \
    (((id) == ZHIANN_BAT_ID1_ID) ||  \
     ((id) == ZHIANN_BAT_ID2_ID) ||  \
     ((id) == ZHIANN_BAT_CMD_ID) ||  \
     ((id) == ZHIANN_BAT_INFO_ID) || \
     ((id) == ZHIANN_BAT_AUX_INFO_ID))

#define ZHIANN_BAT_ID1_SIG      0xE3C317F4D8197BC5ULL
#define ZHIANN_BAT_ID2_SIG      0xF6770593E758B25CULL
#define ZHIANN_BAT_INFO_SIG     0x249C26548A711966ULL
#define ZHIANN_BAT_AUX_INFO_SIG 0x7D7F49FC75484882ULL

#define ZHIANN_BAT_CMD_POWER_ON      1u  // Request battery power on commander
#define ZHIANN_BAT_CMD_POWER_OFF     2u  // Request battery power off commander
#define ZHIANN_BAT_CMD_START_CHARGE  3u  // Request battery start charging
#define ZHIANN_BAT_CMD_STOP_CHARGE   4u  // Request battery stop charging
#define ZHIANN_BAT_CMD_ARM           6u  // Tell battery aircraft in flying
#define ZHIANN_BAT_CMD_DISARM        7u  // Tell battery aircraft not in flying
#define ZHIANN_BAT_CMD_ID_ASSIGN     9u  // Assign battery nodes ID(not used when using dynamic node allocation)
#define ZHIANN_BAT_CMD_VER_BROADCAST 10u // Broadcast battery version and SN meaage

#define ZHIANN_BAT_REQ_TYPE_FLY_CMD 1u
#define ZHIANN_BAT_REQ_TYPE_FLY_ACK 2u
#define ZHIANN_BAT_REQ_TYPE_BAT_CMD 3u
#define ZHIANN_BAT_REQ_TYPE_BAT_ACK 4u
/*-----------------------------------------------------------------------------
 * Data Struct
 ----------------------------------------------------------------------------*/
typedef struct zhiann_bat
{
    U8 bus_id;   // CAN bus ID
    U8 inst_id;  // Instance ID
    U8 dev_id;   // Device ID, 0~7
    U8 cell_cnt; // Number of battery cells
    FP32 volt;   // 电池总电压 v
    FP32 curr;   // 充放电电流 A 正数充电|负数放电
    FP32 pct;    // 剩余容量 % SOC
    FP32 tmp;    // 电池温度 ℃
    // Private data
    U16 status_flags;          // 电池组状态,见电池组状态表
    FP32 avg_power_10sec;      // Average power consumption over the last 10 seconds
    FP32 remaining_cap_wh;     // Will be increasing during charging
    FP32 full_charge_cap_wh;   // Predicted battery capacity when it is fully charged. Falls with aging
    FP32 hours_to_full_charge; // Charging is expected to complete in this time; zero if not charging
    U8 soh;                    // State of Health (SOH) estimate, in pct, Use 127 if SOH cannot be estimated
    U8 soc;                    // Percent of the full charge [0, 100].
    U8 soc_stdev;              // SOC error standard deviation; use best guess if unknown
    bool is_powering_off;

    U16 cell_volt[ZHIANN_BAT_MAX_CELL_CNT]; // mV
    U16 cycle_count;                        // Number of charge/discharge cycles
    U16 over_discharge_count;

    FP32 max_current;
    U32 ts;
} zhiann_bat_t;

typedef struct
{
    U8 cmd;
    U8 type;
    U8 param1;
    U8 param2;
} zhiann_cmd_req_t;

/*-----------------------------------------------------------------------------
 * Public functions
 -----------------------------------------------------------------------------*/
/**
 * @brief initialize function for battery
 */
bool zhiann_bat_init(zhiann_bat_t* bat, const U8 bus_id);

/*-----------------------------------------------------------------------------
 * internal functions
 ----------------------------------------------------------------------------*/
/**
 * @brief analyze complete packet for zhiann battery
 * @param[in]  device instance of zhiann battery receiver
 * @param[in]  msg_id Message ID
 * @param[in]  data Data buffer pointer
 * @param[in]  len Data buffer length
 */
void zhiann_bat_analyze(zhiann_bat_t* bat, const U16 msg_id, const U8* data, const U8 len);

END_DECLS

#endif //~BAT_ZHIANN_H
